use std::sync::Mutex;
use serde::de::Error;
use sqlx::{PgPool, postgres::{PgPoolOptions, PgRow}, Postgres,Pool};

// type Result<T> = Result<T,sqlx::Error>;
type PgResult<T> = Result<T,sqlx::Error>;
use crate::models::{User, Guide, Comment, Help, HelpAnswer, ImageShare, ModRecommendation, UserAttach};


async fn get_pool() -> Result<PgPool,sqlx::Error> {

    let pool = PgPoolOptions::new()
    .max_connections(5)
    .connect("postgres://postgres:mysecretpassword@localhost/back_server").await?;
    //
    // let x = pool.clone();
    Ok(pool)
}


impl User{
    //c

    ///将新数据插入到 user_info表中，并返回该数据的id
    pub async fn insert(nickname:String,email:String,phone_number:String,password:String,friends:Vec<i32>) -> PgResult<i32>{
        let pool = get_pool().await?;

        let status = "active".to_string();
        let res = sqlx::query!(r#"insert into user_info(nickname,email,phone_number,password,friends,status) values($1,$2,$3,$4,$5,$6) returning id"#,
                nickname,
                email,
                phone_number,
                password,
                &friends,
                status,
            )
            .fetch_one(&pool)
            .await?;

        // 新建用户时，对应的附件也要新建。
        let _attachment_id = UserAttach::insert(res.id, vec![], vec![], vec![]).await?;
        // pool.close().await;
        pool.close().await;
        Ok(res.id)
    }
    //u

    // /// 将数据更新
    // pub async fn update_all_by_id(id:i32,nickname:String,email:String,phone_number:String,password:String,friends:Vec<i32>,status:String) -> PgResult<bool> {
    //     let pool = get_pool().await?;
    //     let rows_affected = sqlx::query!(
    //         r#"update user_info
    //         set nickname = $1, email = $2, phone_number = $3, password = $4, friends = $5, status = $6 where id = $7"#,
    //         nickname,email,phone_number,password,&friends,status,id
    //     ).execute(&pool).await?.rows_affected();
    //     Ok(rows_affected > 0)
    // }
    /// 添加好友
    pub async fn add_friends(&mut self,friend_id:i32) -> PgResult<bool> {
        let mut attachment = UserAttach::fetch_one_by_user_id(self.id).await?;
        if attachment.request_list.contains(&friend_id) {
            _ = attachment.pop_request(friend_id).await?;
        }
        
        // let mut user = Self::fetch_one_by_id(self.id).await?;
        if !self.friends.contains(&friend_id) {
            // 1. 先将friend_id添加到自己的friends数组中，
            self.friends.push(friend_id);
        }

        let mut user = Self::fetch_one_by_id(friend_id).await?;

        if !user.friends.contains(&self.id){
            // 2. 将自己的id添加到friend的friends数组中，
            user.friends.push(self.id);
        }

        let pool = get_pool().await?;
        let rows_affected1 = sqlx::query!(
            r#"update user_info 
            set friends = $1 where id = $2"#,
            &self.friends,self.id
        ).execute(&pool).await?.rows_affected();

        let rows_affected2 = sqlx::query!(
            r#"update user_info
            set friends = $1 where id = $2"#,
            &user.friends,user.id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected1 > 0 && rows_affected2 > 0)
    }


    /// 更新昵称
    pub async fn update_nickname(&mut self,nickname:String) -> PgResult<bool> {
        self.nickname = nickname;
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update user_info 
            set nickname = $1 where id = $2"#,
            self.nickname,self.id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    /// 更新邮箱
    pub async fn update_email(&mut self,email:String) -> PgResult<bool> {
        self.email = email;
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update user_info 
            set email = $1 where id = $2"#,
            self.email,self.id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    /// 更新手机号
    pub async fn update_phone_number(&mut self,phone_number:String) -> PgResult<bool> {
        self.phone_number = phone_number;
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update user_info 
            set phone_number = $1 where id = $2"#,
            self.phone_number,self.id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    /// 更新密码
    pub async fn update_password(&mut self,password:String) -> PgResult<bool> {
        self.password = password;
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update user_info 
            set password = $1 where id = $2"#,
            self.password,self.id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    /// 禁言用户
    pub async fn suspend_user_by_id(user_id:i32) -> PgResult<bool> {
        let mut user = User::fetch_one_by_id(user_id).await?;
        user.status = "suspend".to_string();

        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update user_info
            set status = $1 where id = $2"#,
            user.status,user_id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    /// 封禁用户
    pub async fn forbid_user_by_id(user_id:i32) -> PgResult<bool> {
        let mut user = User::fetch_one_by_id(user_id).await?;
        user.status = "forbid".to_string();

        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update user_info
            set status = $1 where id = $2"#,
            user.status,user_id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    /// 正常态用户
    pub async fn active_user_by_id(user_id:i32) -> PgResult<bool> {
        let mut user = User::fetch_one_by_id(user_id).await?;
        user.status = "active".to_string();

        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update user_info
            set status = $1 where id = $2"#,
            user.status,user_id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }




    //r
    /// 根据id查找用户
    pub async fn fetch_one_by_id(id:i32) -> PgResult<User> {
        let pool = get_pool().await?;

        let res = sqlx::query_as!(User,
            r#"select * from user_info where id = $1 order by id desc"#, id
        ).fetch_one(&pool).await?;
        pool.close().await;
        Ok(res)
    }
    
    /// 根据邮箱地址查找用户
    pub async fn fetch_one_by_email(email:String) -> PgResult<User> {
        let pool = get_pool().await?;

        let res = sqlx::query_as!(User,
            r#"select * from user_info where email = $1 order by id desc"#, email
        ).fetch_one(&pool).await?;
        pool.close().await;
        Ok(res)
    }

    /// 根据手机号码查找用户
    pub async fn fetch_one_by_phone_number(phone_number:String) -> PgResult<User> {
        let pool = get_pool().await?;

        let res = sqlx::query_as!(User,
            r#"select * from user_info where phone_number = $1 order by id desc"#, phone_number
        ).fetch_one(&pool).await?;
        pool.close().await;
        Ok(res)
    }

    /// 获取user_info表的所有数据
    pub async fn fetch_all() -> PgResult<Vec<User>> {
        let pool = get_pool().await?;
        let res = sqlx::query_as!(User,
            r#"select * from user_info order by id desc"#
        ).fetch_all(&pool).await?;
        pool.close().await;
        Ok(res)
    }

    /// 获取好友请求列表
    pub async fn get_request_list(&self) -> PgResult<Vec<User>> {
        let attachment = UserAttach::fetch_one_by_user_id(self.id).await?;
        let lists = attachment.get_request_list().await?;

        Ok(lists)
    }


    /// 将其他用户的好友请求添加到列表中去
    pub async fn push_request(&mut self,user_id:i32) -> PgResult<bool> {
        // self.request_list.push(user_id);
        let mut attachment = UserAttach::fetch_one_by_user_id(self.id).await?;
        // attachment.request_list.push(user_id);
        let res = attachment.push_request(user_id).await?;
        //数据库操作

        Ok(res)
    }

    /// 将好友推荐的guide放到recom_guide数组中
    pub async fn push_recom_guide(&self,guide_id:i32) -> PgResult<bool> {
        let mut attachment = UserAttach::fetch_one_by_user_id(self.id).await?;

        let res = attachment.push_recom_guide(guide_id).await?;

        Ok(res)
    }

    /// 将好友推荐的guide放到recom_guide数组中
    pub async fn push_recom_friend(&self,friend_id:i32) -> PgResult<bool> {
        let mut attachment = UserAttach::fetch_one_by_user_id(self.id).await?;

        let res = attachment.push_recom_friend(friend_id).await?;

        Ok(res)
    }


    /// 获取好友推荐攻略列表
    pub async fn get_recom_guide(&self) -> PgResult<Vec<Guide>> {
        let attachment = UserAttach::fetch_one_by_user_id(self.id).await?;
        let lists = attachment.get_recom_guide().await?;

        Ok(lists)
    }

    /// 获取好友推荐用户列表
    pub async fn get_recom_friend(&self) -> PgResult<Vec<User>> {
        let attachment = UserAttach::fetch_one_by_user_id(self.id).await?;
        let lists = attachment.get_recom_friend().await?;
        // println!("{:#?}",attachment);
        Ok(lists)
    }

    /// 获取用户头像
    pub async fn get_user_image(&self) -> PgResult<String> {
        let attachment = UserAttach::fetch_one_by_user_id(self.id).await?;
        Ok(attachment.user_image)
    }

    /// 更新用户头像
    pub async fn update_user_image(&self,image:String) -> PgResult<bool> {
        let mut attachment = UserAttach::fetch_one_by_user_id(self.id).await?;
        let res = attachment.setUserImage(image).await?;
        Ok(res)
    }

    /// 请求加好友
    pub async fn apply_for_new_friend(&self,new_friend_id:i32) -> PgResult<bool> {
        let mut user = Self::fetch_one_by_id(new_friend_id).await?;
        let res = user.push_request(self.id).await?;
        Ok(res)
    }

    // D

    /// 通过id值删除User
    pub async fn delete_by_id(id:i32) -> PgResult<bool> {
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"delete from user_info where id = $1"#, id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    /// 删除好友
    pub async fn delete_friend(&mut self,user_id:i32) -> PgResult<bool> {
        for (index,id) in self.friends.iter().enumerate() {
            if id == &user_id{
                self.friends.remove(index);
                break;
            }
        }


        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update user_info
            set friends = $1 where id = $2"#,
            &self.friends,self.id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

}

impl Guide {
    //c

    /// 新建Guide，返回id
    pub async fn insert(author_id:i32,guide_type:String,content:String,image:String,comments:Vec<i32>) -> PgResult<i32> {
        let pool = get_pool().await?;
        let status = "active".to_string();
        let res = sqlx::query!(r#"insert into guide(author_id,guide_type,content,image,comments,status) values($1,$2,$3,$4,$5,$6) returning id"#,
                author_id,
                guide_type,
                content,
                image,
                &comments,
                status,
            )
            .fetch_one(&pool)
            .await?;
        pool.close().await;
        Ok(res.id)
    }
    //u

    // /// 将数据更新
    // pub async fn update_all_by_id(id:i32,guide_type:String,content:String,image:String,comments:Vec<i32>,status:String) -> PgResult<bool> {
    //     let pool = get_pool().await?;
    //     let rows_affected = sqlx::query!(
    //         r#"update guide
    //         set guide_type = $1, content = $2, image = $3, comments = $4, status = $5 where id = $6"#,
    //         guide_type,content,image,&comments,status,id
    //     ).execute(&pool).await?.rows_affected();
    //     Ok(rows_affected > 0)
    // }

     /// 将数据更新,只更新 type、content以及image
    pub async fn update_part_by_id(id:i32,guide_type:String,content:String,image:String)-> PgResult<bool> {
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update guide 
            set guide_type = $1, content = $2, image = $3 where id = $4"#,
            guide_type,content,image,id
        ).execute(&pool).await?.rows_affected();

        pool.close().await;
        Ok(rows_affected > 0)
    }

    pub async fn update_type_and_content_by_id(id:i32,guide_type:String,content:String) -> PgResult<bool>{
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update guide
            set guide_type = $1, content = $2 where id = $3"#,
            guide_type,content,id
        ).execute(&pool).await?.rows_affected();

        pool.close().await;
        Ok(rows_affected > 0)
    }

    /// 将guide设置为审核态
    pub async fn suspend_guide_by_id(guide_id:i32) -> PgResult<bool> {
        let mut guide = Guide::fetch_one_by_id(guide_id).await?;
        guide.status = "suspend".to_string();
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update guide
            set status = $1 where id = $2"#,
            guide.status, guide_id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    /// 将guide设置为封禁态
    pub async fn forbid_guide_by_id(guide_id:i32) -> PgResult<bool> {
        let mut guide = Guide::fetch_one_by_id(guide_id).await?;
        guide.status = "forbid".to_string();
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update guide
            set status = $1 where id = $2"#,
            guide.status, guide_id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    /// 将guide设置为精华态
    pub async fn prime_guide_by_id(guide_id:i32) -> PgResult<bool> {
        let mut guide = Guide::fetch_one_by_id(guide_id).await?;
        guide.status = "prime".to_string();
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update guide
            set status = $1 where id = $2"#,
            guide.status, guide_id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    /// 将guide设置为正常态
    pub async fn active_guide_by_id(guide_id:i32) -> PgResult<bool> {
        let mut guide = Guide::fetch_one_by_id(guide_id).await?;
        guide.status = "active".to_string();
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update guide
            set status = $1 where id = $2"#,
            guide.status, guide_id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }



    /// 添加comment
    pub async fn push_comment_by_id(id:i32,comment_id:i32) -> PgResult<bool> {

        let mut guide = Self::fetch_one_by_id(id).await?;

        if !guide.comments.contains(&comment_id) {
            guide.comments.push(comment_id);
        }

        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update guide 
            set comments = $1 where id = $2"#,
            &guide.comments,id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    /// 删除comment
    pub async fn pop_comment_by_id(id:i32, comment_id:i32) -> PgResult<bool> {
        let mut guide = Self::fetch_one_by_id(id).await?;

        for (index,c_id) in guide.comments.iter().enumerate() {
            if c_id == &comment_id {
                guide.comments.remove(index);
                break;
            }
        }

        // if guide.comments.contains(&comment_id) {
            
        // }

        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update guide 
            set comments = $1 where id = $2"#,
            &guide.comments,id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)

    }

    //r

    /// 根据id查找guide
    pub async fn fetch_one_by_id(id:i32) -> PgResult<Guide> {
        let pool = get_pool().await?;

        let res = sqlx::query_as!(Guide,
            r#"select * from guide where id = $1 order by id desc"#, id
        ).fetch_one(&pool).await?;
        pool.close().await;
        Ok(res)
    }


    /// 根据作者id查找guide
    pub async fn fetch_all_by_author_id(author_id:i32) -> PgResult<Vec<Guide>> {
        let pool = get_pool().await?;

        let res = sqlx::query_as!(Guide,
            r#"select * from guide where author_id = $1 order by id desc"#, author_id
        ).fetch_all(&pool).await?;
        pool.close().await;
        Ok(res)
    }

    /// 根据guide_type查找guide
    pub async fn fetch_all_by_guide_type(guide_type:String) -> PgResult<Vec<Guide>> {
        let pool = get_pool().await?;

        let res = sqlx::query_as!(Guide,
            r#"select * from guide where guide_type = $1 order by id desc"#, guide_type
        ).fetch_all(&pool).await?;
        pool.close().await;
        Ok(res)
    }

    /// 获取guide表的所有数据
    pub async fn fetch_all() -> PgResult<Vec<Guide>> {
        let pool = get_pool().await?;
        let res = sqlx::query_as!(Guide,
            r#"select * from guide order by id desc"#
        ).fetch_all(&pool).await?;
        pool.close().await;
        Ok(res)
    }


    /// 获取id号为参数的guide数据项 的所有评论
    pub async fn fetch_comments_of(id:i32) -> PgResult<Vec<Comment>> {
        let mut comments = vec![];
        let mut guide = Self::fetch_one_by_id(id).await?;
        guide.comments.sort();
        println!("{:#?}",guide.comments);
        for comment_id in guide.comments {
            //使用Comment的API查找对应commend_id的Comment

            let comment =  Comment::fetch_one_by_id(comment_id).await?;
            //然后将这些Comment对象添加到vec中
            comments.push(comment);
        }

        Ok(comments)
    }

    // D

    /// 通过id值删除guide
    pub async fn delete_by_id(id:i32) -> PgResult<bool> {
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"delete from guide where id = $1"#, id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }
}

impl Comment {
    //c
    /// 新建comment，返回id
    pub async fn insert(author_id:i32,content:String,rate:String,status:String) -> PgResult<i32> {
        let pool = get_pool().await?;
        let res = sqlx::query!(r#"insert into comments (author_id,content,rate,status) values($1,$2,$3,$4) returning id"#,
                author_id,
                content,
                rate,
                status,
            )
            .fetch_one(&pool)
            .await?;
        pool.close().await;
        Ok(res.id)
    }
    

    //r

    /// 根据comment的id查找comment
    pub async fn fetch_one_by_id(id:i32) -> PgResult<Comment> {
        let pool = get_pool().await?;

        let res = sqlx::query_as!(Comment,
            r#"select * from comments where id = $1 order by id desc"#, id
        ).fetch_one(&pool).await?;
        pool.close().await;
        Ok(res)
    
    }

    /// 根据作者id查找comment
    pub async fn fetch_all_by_author_id(author_id:i32) -> PgResult<Vec<Comment>> {
        let pool = get_pool().await?;

        let res = sqlx::query_as!(Comment,
            r#"select * from comments where author_id = $1 order by id desc"#, author_id
        ).fetch_all(&pool).await?;
        pool.close().await;
        Ok(res)
    }

    /// 根据rate查找comment
    pub async fn fetch_all_by_rate(rate:String) -> PgResult<Vec<Comment>> {
        let pool = get_pool().await?;

        let res = sqlx::query_as!(Comment,
            r#"select * from comments where rate = $1 order by id desc"#, rate
        ).fetch_all(&pool).await?;
        pool.close().await;
        Ok(res)
    }

    /// 获取comments表的所有数据
    pub async fn fetch_all() -> PgResult<Vec<Comment>> {    //应该用不上这个函数
        let pool = get_pool().await?;
        let res = sqlx::query_as!(Comment,
            r#"select * from comments order by id desc"#
        ).fetch_all(&pool).await?;
        pool.close().await;
        Ok(res)
    }

    
    //u

    // /// 将数据全部更新
    // pub async fn update_all_by_id(id:i32,content:String,rate:String,status:String) -> PgResult<bool> {
    //     let pool = get_pool().await?;
    //     let rows_affected = sqlx::query!(
    //         r#"update comments
    //         set content = $1, rate = $2, status = $3 where id = $4"#,
    //         content,rate,status,id
    //     ).execute(&pool).await?.rows_affected();
    //     Ok(rows_affected > 0)
    // }

    /// 将数据部分更新
    pub async fn update_part_by_id(id:i32,content:String,rate:String) -> PgResult<bool> {
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update comments 
            set content = $1, rate = $2 where id = $3"#,
            content,rate,id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }
    /// 将comment设置为审核态
    pub async fn suspend_comment_by_id(comment_id:i32) -> PgResult<bool> {
        let mut comment = Comment::fetch_one_by_id(comment_id).await?;
        comment.status = "suspend".to_string();
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update comments
            set status = $1 where id = $2"#,
            comment.status, comment_id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    /// 将comment设置为封禁态
    pub async fn forbid_comment_by_id(comment_id:i32) -> PgResult<bool> {
        let mut comment = Comment::fetch_one_by_id(comment_id).await?;
        comment.status = "forbid".to_string();
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update comments
            set status = $1 where id = $2"#,
            comment.status, comment_id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    /// 将comment设置为精华态
    pub async fn prime_comment_by_id(comment_id:i32) -> PgResult<bool> {
        let mut comment = Comment::fetch_one_by_id(comment_id).await?;
        comment.status = "prime".to_string();
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update comments
            set status = $1 where id = $2"#,
            comment.status, comment_id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    /// 将comment设置为正常态
    pub async fn active_comment_by_id(comment_id:i32) -> PgResult<bool> {
        let mut comment = Comment::fetch_one_by_id(comment_id).await?;
        comment.status = "active".to_string();
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update comments
            set status = $1 where id = $2"#,
            comment.status, comment_id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }



    // D

    /// 通过id值删除comment
    pub async fn delete_by_id(id:i32) -> PgResult<bool> {
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"delete from comments where id = $1"#, id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }
}

impl Help {
    //c

    /// 返回id
    pub async fn insert(author_id:i32,theme:String,content:String,image:String,answers:Vec<i32>,status:String) -> PgResult<i32> {
        let pool = get_pool().await?;
        let res = sqlx::query!(r#"insert into help (author_id,theme,content,image,answers,status) values($1,$2,$3,$4,$5,$6) returning id"#,
                author_id,
                theme,
                content,
                image,
                &answers,
                status,
            )
            .fetch_one(&pool)
            .await?;
        pool.close().await;
        Ok(res.id)
    }


    //r

    /// 根据help的id查找help
    pub async fn fetch_one_by_id(id:i32) -> PgResult<Help> {
        let pool = get_pool().await?;

        let res = sqlx::query_as!(Help,
            r#"select * from help where id = $1 order by id desc"#, id
        ).fetch_one(&pool).await?;
        pool.close().await;
        Ok(res)
    
    }

    /// 根据作者id查找Help
    pub async fn fetch_all_by_author_id(author_id:i32) -> PgResult<Vec<Help>> {
        let pool = get_pool().await?;

        let res = sqlx::query_as!(Help,
            r#"select * from help where author_id = $1 order by id desc"#, author_id
        ).fetch_all(&pool).await?;
        pool.close().await;
        Ok(res)
    }

    /// 根据theme查找help
    pub async fn fetch_all_by_theme(theme:String) -> PgResult<Vec<Help>> {
        let pool = get_pool().await?;

        let res = sqlx::query_as!(Help,
            r#"select * from help where theme = $1 order by id desc"#, theme
        ).fetch_all(&pool).await?;
        pool.close().await;
        Ok(res)
    }

    /// 返回对应id的Help对象的所有answers
    pub async fn fetch_all_answers_of(id:i32) -> PgResult<Vec<HelpAnswer>> {
        let mut answers = vec![];
        let help = Self::fetch_one_by_id(id).await?;
        for answer_id in help.answers {
            //使用HelpAnswer的API查找对应 answer_id的HelpAnswer
            let answer = HelpAnswer::fetch_one_by_id(answer_id).await?;
            //然后将它们添加到vec中
            answers.push(answer);
        }

        Ok(answers)
    }

    /// 返回所有求助贴
    pub async fn fetch_all() -> PgResult<Vec<Help>> {
        let pool = get_pool().await?;

        let res = sqlx::query_as!(Help,
            r#"select * from help order by id desc"#,
        ).fetch_all(&pool).await?;
        pool.close().await;
        Ok(res)
    }


    //u

    /// 将所有数据更新
    pub async fn update_all_by_id(id:i32,theme:String,content:String,image:String,answers:Vec<i32>,status:String) -> PgResult<bool> {
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update help 
            set theme = $1, content = $2, image = $3, answers = $4, status = $5 where id = $6"#,
            theme,content,image,&answers,status,id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }


    /// 将部分数据更新
    pub async fn update_part_by_id(id:i32,theme:String,content:String,image:String) -> PgResult<bool> {
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update help 
            set theme = $1, content = $2, image = $3 where id = $4"#,
            theme,content,image,id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    /// 添加答案
    pub async fn push_answer(&mut self,answer_id:i32) -> PgResult<bool> {
        if !self.answers.contains(&answer_id) {
            self.answers.push(answer_id); 
        }
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update help 
            set answers = $1 where id = $2"#,
            &self.answers,self.id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)

        // sqlx::Error
        
    }

    /// 删除答案
    pub async fn pop_answer(&mut self,answer_id:i32) -> PgResult<bool> {
        // if !self.answers.contains(&answer_id) {
        //     self.answers.push(answer_id); 
        // }

        for (index,a_id) in self.answers.iter().enumerate() {
            if a_id == &answer_id {
                self.answers.remove(index);
                break;
            }
        }
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update help 
            set answers = $1 where id = $2"#,
            &self.answers,self.id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    } 


    //d

    /// 通过id值删除help
    pub async fn delete_by_id(id:i32) -> PgResult<bool> {
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"delete from help where id = $1"#, id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }
    

}

impl HelpAnswer {
    //c

    /// 返回id
    pub async fn insert(author_id:i32,help_id:i32,content:String,image:String,status:String) -> PgResult<i32> {
        let pool = get_pool().await?;
        let res = sqlx::query!(r#"insert into help_answer (author_id,help_id,content,image,status) values($1,$2,$3,$4,$5) returning id"#,
                author_id,
                help_id,
                content,
                image,
                status,
            )
            .fetch_one(&pool)
            .await?;
        pool.close().await;
        Ok(res.id)
    }


    //r

    /// 根据help_answer的id查找help
    pub async fn fetch_one_by_id(id:i32) -> PgResult<HelpAnswer> {
        let pool = get_pool().await?;

        let res = sqlx::query_as!(HelpAnswer,
            r#"select * from help_answer where id = $1 order by id desc"#, id
        ).fetch_one(&pool).await?;
        pool.close().await;
        Ok(res)
    
    }

    /// 根据作者id查找HelpAnswer
    pub async fn fetch_all_by_author_id(author_id:i32) -> PgResult<Vec<HelpAnswer>> {
        let pool = get_pool().await?;

        let res = sqlx::query_as!(HelpAnswer,
            r#"select * from help_answer where author_id = $1 order by id desc"#, author_id
        ).fetch_all(&pool).await?;

        pool.close().await;
        Ok(res)
    }

    /// 根据help_id查找HelpAnswer
    pub async fn fetch_all_by_help_id(help_id:i32) -> PgResult<Vec<HelpAnswer>> {
        let pool = get_pool().await?;

        let res = sqlx::query_as!(HelpAnswer,
            r#"select * from help_answer where help_id = $1 order by id desc"#, help_id
        ).fetch_all(&pool).await?;

        pool.close().await;
        Ok(res)
    }


    //u

    /// 将数据全部更新
    pub async fn update_all_by_id(id:i32,content:String,image:String,status:String) -> PgResult<bool> {
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update help_answer 
            set content = $1, image = $2, status = $3 where id = $4"#,
            content,image,status,id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    /// 将数据部分更新
    pub async fn update_part_by_id(id:i32,content:String,image:String) -> PgResult<bool> {
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update help_answer 
            set content = $1, image = $2 where id = $3"#,
            content,image,id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }


    //d

    /// 通过id值删除HelpAnswer
    pub async fn delete_by_id(id:i32) -> PgResult<bool> {
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"delete from help_answer where id = $1"#, id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }
}

impl ImageShare {
    //c

    /// 新建ImageShare，返回id
    pub async fn insert(author_id:i32,image:String,content:String,image_type:String,comments:Vec<i32>,status:String) -> PgResult<i32> {
        let pool = get_pool().await?;
        let res = sqlx::query!(r#"insert into image_share (author_id,image,content,image_type,comments,status) values($1,$2,$3,$4,$5,$6) returning id"#,
                author_id,
                image,
                content,
                image_type,
                &comments,
                status,
            )
            .fetch_one(&pool)
            .await?;

        pool.close().await;
        Ok(res.id)
    }
    //u

    /// 将数据全部更新
    pub async fn update_all_by_id(id:i32,image:String,content:String,image_type:String,comments:Vec<i32>,status:String) -> PgResult<bool> {
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update image_share 
            set image = $1, content = $2, image_type = $3, comments = $4, status = $5 where id = $6"#,
            image,content,image_type,&comments,status,id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    /// 将数据部分更新
    pub async fn update_part_by_id(id:i32,image:String,content:String,image_type:String) -> PgResult<bool> {
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update image_share 
            set image = $1, content = $2, image_type = $3 where id = $4"#,
            image,content,image_type,id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    /// 添加评论
    pub async fn push_comment(&mut self,comment_id:i32) -> PgResult<bool> {

        if !self.comments.contains(&comment_id) {
            self.comments.push(comment_id);
        }

        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update image_share 
            set comments = $1 where id = $2"#,
            &self.comments,self.id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    /// 删除评论(仅删除了mod_recommendation表中的引用)
    pub async fn pop_comment(&mut self,comment_id:i32) -> PgResult<bool> {
        // if !self.answers.contains(&answer_id) {
        //     self.answers.push(answer_id); 
        // }

        for (index,c_id) in self.comments.iter().enumerate() {
            if c_id == &comment_id {
                self.comments.remove(index);
                break;
            }
        }
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update image_share 
            set comments = $1 where id = $2"#,
            &self.comments,self.id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    } 


    //r

    /// 根据id查找ImageShare
    pub async fn fetch_one_by_id(id:i32) -> PgResult<ImageShare> {
        let pool = get_pool().await?;

        let res = sqlx::query_as!(ImageShare,
            r#"select * from image_share where id = $1 order by id desc"#, id
        ).fetch_one(&pool).await?;

        pool.close().await;
        Ok(res)
    }


    /// 根据作者id查找ImageShare
    pub async fn fetch_all_by_author_id(author_id:i32) -> PgResult<Vec<ImageShare>> {
        let pool = get_pool().await?;

        let res = sqlx::query_as!(ImageShare,
            r#"select * from image_share where author_id = $1 order by id desc"#, author_id
        ).fetch_all(&pool).await?;

        pool.close().await;
        Ok(res)
    }

    /// 根据image_type查找ImageShare
    pub async fn fetch_all_by_guide_type(image_type:String) -> PgResult<Vec<ImageShare>> {
        let pool = get_pool().await?;

        let res = sqlx::query_as!(ImageShare,
            r#"select * from image_share where image_type = $1 order by id desc"#, image_type
        ).fetch_all(&pool).await?;

        pool.close().await;
        Ok(res)
    }

    /// 获取image_share表的所有数据
    pub async fn fetch_all() -> PgResult<Vec<ImageShare>> {
        let pool = get_pool().await?;
        let res = sqlx::query_as!(ImageShare,
            r#"select * from image_share order by id desc"#
        ).fetch_all(&pool).await?;

        pool.close().await;
        Ok(res)
    }


    /// 获取id号为参数的ImageShare数据项 的所有评论
    pub async fn fetch_comments_of(id:i32) -> PgResult<Vec<Comment>> {
        let mut comments = vec![];
        let image_share = Self::fetch_one_by_id(id).await?;
        
        for comment_id in image_share.comments {
            //使用Comment的API查找对应commend_id的Comment

            let comment =  Comment::fetch_one_by_id(comment_id).await?;
            //然后将这些Comment对象添加到vec中
            comments.push(comment);
        }

        Ok(comments)
    }

    pub async fn fetch_recommendation() -> PgResult<Vec<ImageShare>> {
        // let mut pool = get_pool().await?;

        let mut results = vec![];
        // let mut stream = sqlx::query_as::<_,ImageShare>(r#"select i.* from image_share i inner join comments c on (c.id = any(i.comments)) and c.rate = '5'"#)
        // .fetch(&mut pool);

        let comments = Comment::fetch_all().await.unwrap();
        let shares = Self::fetch_all().await.unwrap();

        for share in &shares{
            for c in &comments {
                if share.comments.contains(&c.id) && c.rate == "5".to_string(){
                    results.push(share.clone());
                }
            }
        }

        // let res = sqlx::query_as!(ImageShare,
        //     r#"select i.* from image_share i inner join comments c on (c.id = any(i.comments)) and c.rate = '5'"#
        // )
        // .fetch_optional(&pool).await;

        // let mut stream = sqlx::query(r#"select i.* from image_share i inner join comments c on (c.id = any(i.comments)) and c.rate = '5'"#)
        // .map(|row:PgRow|{
        //     // results.push(image_share);
            
        // })
        // .fetch_all(&pool);
            
        


        // let res = sqlx::query_as!(ImageShare,
        //     r#"
        //     select i.* from image_share i inner join comments c on (c.id = any(i.comments)) and c.rate = '5'
        //     "#
        // ).fetch_all(&pool).await?;

        // Ok(res)
        Ok(results)
    }

    // D

    /// 通过id值删除ImageShare
    pub async fn delete_by_id(id:i32) -> PgResult<bool> {
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"delete from image_share where id = $1"#, id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }
}

impl ModRecommendation {
    //c

    /// 新建ModRecommendation，返回id
    pub async fn insert(author_id:i32,content:String,mod_type:String,compatibility:String,module_author:String,module_origin:String,image:String,comments:Vec<i32>,status:String) -> PgResult<i32> {
        let pool = get_pool().await?;
        let res = sqlx::query!(r#"insert into mod_recommendation (author_id,content,mod_type,compatibility,module_author,module_origin,image,comments,status) values($1,$2,$3,$4,$5,$6,$7,$8,$9) returning id"#,
                author_id,
                content,
                mod_type,
                compatibility,
                module_author,
                module_origin,
                image,
                &comments,
                status,
            )
            .fetch_one(&pool)
            .await?;

        pool.close().await;
        Ok(res.id)
    }
    //u

    /// 将数据全部更新
    pub async fn update_all_by_id(id:i32,content:String,mod_type:String,compatibility:String,module_author:String,module_origin:String,image:String,comments:Vec<i32>,status:String) -> PgResult<bool> {
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update mod_recommendation 
            set content = $1, mod_type = $2, compatibility = $3, module_author = $4, module_origin = $5, image = $6, comments = $7, status = $8 where id = $9"#,
            content,mod_type,compatibility,module_author,module_origin,image,&comments,status,id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    /// 将数据部分更新
    pub async fn update_part_by_id(id:i32,content:String,mod_type:String,compatibility:String,module_author:String,module_origin:String,image:String) -> PgResult<bool> {
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update mod_recommendation 
            set content = $1, mod_type = $2, compatibility = $3, module_author = $4, module_origin = $5, image = $6 where id = $7"#,
            content,mod_type,compatibility,module_author,module_origin,image,id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }


    /// 添加评论
    pub async fn push_comment(&mut self,comment_id:i32) -> PgResult<bool> {

        if !self.comments.contains(&comment_id) {
            self.comments.push(comment_id);
        }

        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update mod_recommendation 
            set comments = $1 where id = $2"#,
            &self.comments,self.id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    /// 删除评论(仅删除了mod_recommendation表中的引用)
    pub async fn pop_comment(&mut self,comment_id:i32) -> PgResult<bool> {
        // if !self.answers.contains(&answer_id) {
        //     self.answers.push(answer_id); 
        // }

        for (index,c_id) in self.comments.iter().enumerate() {
            if c_id == &comment_id {
                self.comments.remove(index);
                break;
            }
        }
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update mod_recommendation 
            set comments = $1 where id = $2"#,
            &self.comments,self.id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    } 


    //r

    /// 根据id查找ModRecommendation
    pub async fn fetch_one_by_id(id:i32) -> PgResult<Self> {
        let pool = get_pool().await?;

        let res = sqlx::query_as!(Self,
            r#"select * from mod_recommendation where id = $1 order by id desc"#, id
        ).fetch_one(&pool).await?;
        pool.close().await;
        
        Ok(res)
    }


    /// 根据作者id查找ModRecommendation
    pub async fn fetch_all_by_author_id(author_id:i32) -> PgResult<Vec<Self>> {
        let pool = get_pool().await?;

        let res = sqlx::query_as!(Self,
            r#"select * from mod_recommendation where author_id = $1 order by id desc"#, author_id
        ).fetch_all(&pool).await?;

        pool.close().await;
        Ok(res)
    }


    /// 根据mod_type查找ModRecommendation
    pub async fn fetch_all_by_guide_type(mod_type:String) -> PgResult<Vec<Self>> {
        let pool = get_pool().await?;

        let res = sqlx::query_as!(Self,
            r#"select * from mod_recommendation where mod_type = $1 order by id desc"#, mod_type
        ).fetch_all(&pool).await?;

        pool.close().await;
        Ok(res)
    }
    /// 根据compatibility查找ModRecommendation
    pub async fn fetch_all_by_compatibility(compatibility:String) -> PgResult<Vec<Self>> {
        let pool = get_pool().await?;

        let res = sqlx::query_as!(Self,
            r#"select * from mod_recommendation where compatibility = $1 order by id desc"#, compatibility
        ).fetch_all(&pool).await?;

        pool.close().await;
        Ok(res)
    }

    /// 根据module_author查找ModRecommendation
    pub async fn fetch_all_by_module_author(module_author:String) -> PgResult<Vec<Self>> {
        let pool = get_pool().await?;

        let res = sqlx::query_as!(Self,
            r#"select * from mod_recommendation where module_author = $1 order by id desc"#, module_author
        ).fetch_all(&pool).await?;

        pool.close().await;
        Ok(res)
    }

    /// 根据module_origin查找ModRecommendation
    pub async fn fetch_all_by_module_origin(module_origin:String) -> PgResult<Vec<Self>> {
        let pool = get_pool().await?;

        let res = sqlx::query_as!(Self,
            r#"select * from mod_recommendation where module_origin = $1 order by id desc"#, module_origin
        ).fetch_all(&pool).await?;

        pool.close().await;
        Ok(res)
    }

    /// 获取mod_recommendation表的所有数据
    pub async fn fetch_all() -> PgResult<Vec<Self>> {
        let pool = get_pool().await?;
        let res = sqlx::query_as!(Self,
            r#"select * from mod_recommendation order by id desc"#
        ).fetch_all(&pool).await?;

        pool.close().await;
        Ok(res)
    }


    /// 获取id号为参数的ModRecommendation数据项 的所有评论
    pub async fn fetch_comments_of(id:i32) -> PgResult<Vec<Comment>> {
        let mut comments = vec![];
        let mod_recommendation = Self::fetch_one_by_id(id).await?;
        
        for comment_id in mod_recommendation.comments {
            //使用Comment的API查找对应commend_id的Comment

            let comment =  Comment::fetch_one_by_id(comment_id).await?;
            //然后将这些Comment对象添加到vec中
            comments.push(comment);
        }

        Ok(comments)
    }

    // D

    /// 通过id值删除ModRecommendation
    pub async fn delete_by_id(id:i32) -> PgResult<bool> {
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"delete from mod_recommendation where id = $1"#, id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }


    pub async fn forbid_by_id(id:i32) -> PgResult<bool> {
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update mod_recommendation set status = 'forbid' where id = $1"#, id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }
    pub async fn prime_by_id(id:i32) -> PgResult<bool> {
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update mod_recommendation set status = 'prime' where id = $1"#, id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }
    pub async fn active_by_id(id:i32) -> PgResult<bool> {
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update mod_recommendation set status = 'active' where id = $1"#, id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }
}

impl UserAttach {
    async fn insert(user_id:i32,request_list:Vec<i32>,guide_recom:Vec<i32>,friend_recom:Vec<i32>) -> PgResult<i32> {
        let pool = get_pool().await?;
        let res = sqlx::query!(r#"insert into user_attach (user_id,request_list,guide_recom,friend_recom) values($1,$2,$3,$4) returning id"#,
                user_id,
                &request_list,
                &guide_recom,
                &friend_recom,
            )
            .fetch_one(&pool)
            .await?;

        pool.close().await;
        Ok(res.id)
    }

    async fn fetch_one_by_id(id:i32) -> PgResult<UserAttach> {
        let pool = get_pool().await?;
        let res = sqlx::query_as!(UserAttach,
            r#"select * from user_attach where id = $1 order by id desc"#, id
        ).fetch_one(&pool).await?;

        pool.close().await;
        Ok(res)
    }

    async fn fetch_one_by_user_id(user_id:i32) -> PgResult<UserAttach> {
        let pool = get_pool().await?;
        let res = sqlx::query_as!(UserAttach,
            r#"select * from user_attach where user_id = $1 order by id desc"#, user_id
        ).fetch_one(&pool).await?;

        pool.close().await;
        Ok(res)
    }

    // async fn update_by_id()
    async fn get_request_list(&self) -> PgResult<Vec<User>> {
        let mut users = vec![];
        for id in &self.request_list {
            let user = User::fetch_one_by_id(id.clone()).await?;
            users.push(user);
        }

        Ok(users)
        // Ok(res)
    }

    async fn push_request(&mut self,user_id:i32) -> PgResult<bool> {
        if !self.request_list.contains(&user_id){
            self.request_list.push(user_id);
        }

        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update user_attach 
            set request_list = $1 where id = $2"#,
            &self.request_list,self.id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    async fn pop_request(&mut self,user_id:i32) -> PgResult<bool> {
        // self.request_list.remove()
        for (index,uid) in self.request_list.iter().enumerate(){
            if uid == &user_id{
                self.request_list.remove(index);
                break;
            }
        }
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update user_attach 
            set request_list = $1 where id = $2"#,
            &self.request_list,self.id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    async fn get_recom_guide(&self) -> PgResult<Vec<Guide>> {
        let mut guides = vec![];
        for guide_id in &self.guide_recom {
            let guide = Guide::fetch_one_by_id(guide_id.clone()).await?;
            guides.push(guide);
        }
        Ok(guides)
    }

    async fn push_recom_guide(&mut self,guide_id:i32) -> PgResult<bool> {
        if !self.guide_recom.contains(&guide_id){
            self.guide_recom.push(guide_id);
        }

        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update user_attach
            set guide_recom = $1 where id = $2"#,
            &self.guide_recom,self.id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    async fn setUserImage(&mut self,image:String) -> PgResult<bool>{
        self.user_image = image;
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
        r#"update user_attach
                set user_image = $1 where id = $2"#,
        self.user_image,self.id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    async fn get_recom_friend(&self) -> PgResult<Vec<User>> {
        let mut friends = vec![];
        for id in &self.friend_recom {
            // println!("I'm in!");
            let user = User::fetch_one_by_id(id.clone()).await?;
            friends.push(user);
        }
        // println!("{:#?}",friends);
        Ok(friends)
    }

    async fn push_recom_friend(&mut self,friend_id:i32) -> PgResult<bool> {
        if !self.friend_recom.contains(&friend_id){
            self.friend_recom.push(friend_id);
        }
        let pool = get_pool().await?;
        let rows_affected = sqlx::query!(
            r#"update user_attach
            set friend_recom = $1 where id = $2"#,
            &self.friend_recom,self.id
        ).execute(&pool).await?.rows_affected();
        pool.close().await;
        Ok(rows_affected > 0)
    }

    // async fn
}